#include "drv8301.h"
#include <stdio.h>   // 用于串口打印（可选）

extern SPI_HandleTypeDef hspi3;   // CubeMX 生成的 SPI 句柄（改成你的）

// ==================== 底层 SPI 传输 ====================
static uint16_t drv8301_transfer(uint16_t txdata)
{
    uint8_t tx[2] = {(txdata >> 8) & 0xFF, txdata & 0xFF};
    uint8_t rx[2] = {0};

    HAL_GPIO_WritePin(DRV8301_CS_GPIO_Port, DRV8301_CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi3, tx, rx, 2, HAL_MAX_DELAY);
    HAL_GPIO_WritePin(DRV8301_CS_GPIO_Port, DRV8301_CS_Pin, GPIO_PIN_SET);

    return (rx[0] << 8) | rx[1];
}

// ==================== 读寄存器 ====================
uint16_t DRV8301_Read(uint8_t addr)
{
    uint16_t cmd = (1 << 15) | ((addr & 0x0F) << 11);   // Read bit + 地址
    drv8301_transfer(cmd);          // 第一次发送命令
    return drv8301_transfer(0x0000); // 第二次读取数据
}

// ==================== 写寄存器 ====================
void DRV8301_Write(uint8_t addr, uint16_t data)
{
    uint16_t cmd = ((addr & 0x0F) << 11) | (data & 0x07FF);   // Write bit=0
    drv8301_transfer(cmd);
}

// ==================== 初始化 DRV8301 ====================
void DRV8301_Init(void)
{
    // 硬件复位时序
    DRV8301_DisableGate();
    HAL_Delay(10);
    DRV8301_EnableGate();
    HAL_Delay(10);

    // 配置 Control Register 1（6x PWM + 过流重试 + 10倍增益）
    DRV8301_Write(DRV_REG_CTRL1, PWM_MODE_6X | OCP_RETRY | GAIN_10);

    // 配置 Control Register 2（死区 400ns）
    DRV8301_Write(DRV_REG_CTRL2, DEADTIME_400NS);

    printf("DRV8301 初始化完成！\r\n");
}

// ==================== 状态读取 ====================
uint16_t DRV8301_ReadStatus1(void) { return DRV8301_Read(DRV_REG_STATUS1); }
uint16_t DRV8301_ReadStatus2(void) { return DRV8301_Read(DRV_REG_STATUS2); }

// ==================== 使能/关闭栅极驱动 ====================
void DRV8301_EnableGate(void)
{
    HAL_GPIO_WritePin(DRV8301_EN_GPIO_Port, DRV8301_EN_Pin, GPIO_PIN_SET);
}
void DRV8301_DisableGate(void)
{
    HAL_GPIO_WritePin(DRV8301_EN_GPIO_Port, DRV8301_EN_Pin, GPIO_PIN_RESET);
}

// ==================== 故障检测 ====================
uint8_t DRV8301_CheckFault(void)
{
    return HAL_GPIO_ReadPin(DRV8301_FAULT_GPIO_Port, DRV8301_FAULT_Pin) == GPIO_PIN_RESET;
}